// JavaScript Document
//在数组中寻找字符串
function inarray(str,findarray){
	for(var i=0;i<findarray.length;i++){
		if(str==findarray[i]) return true;	
	}
	return false;
}
//检测字符是否是分隔字符，字们分别是空格、换行\r 换行\n tab键 这四种
function checksplit(str){
	if(str==' ') return true;
	if(str=='\r') return true;
	if(str=='\n') return true;
	if(str=='\t') return true;
}

//取变量的值,如果没有这个变量，则返加0
function get_variable(varname){
	for(var i=0;i<variable.length;i++){
		if(varname==variable[i].name) return 	variable[i].value;
	}
	return 0;
}

//设置变量的值，如果没有这个变量，则创建这个变量
function set_variable(varname,value){
	var find_var=false;
	for(var i=0;i<variable.length;i++){
		if(variable[i].name==varname)
		{
		 	variable[i].value=value;
			find_var=true;
			break;
		}
	}
	if(!find_var){//创建新变量
		variable[variable.length]={name:varname,value:value};
	}
}
function checkletter(ch){
	var reg= /^[A-Za-z]+$/;
	return reg.test(ch);
}
function checknumber(ch){
	var reg= /^[0-9]+$/;
	return reg.test(ch);
}



//判断是否是操作符
function IsOperator(ch)
{
    if(ch=='+' || ch=='-' || ch=='*' || ch=='/') return true; else return false;
}

/* 比较两个操作符的优先级
op1==( 输出 -1
op1比op2低级 输出-1
op1比op2高级 输出1
op1和op2同级 输出0
*/
function Precedence(op1, op2)
{
    if (op1 == '(')
    {
        return -1;
    }

    if (op1 == '+' || op1 == '-')
    {
        if (op2 == '*' || op2 == '/')
        {
            return -1;
        }
        else
        {
            return 0;
        }
    }

    if (op1 == '*' || op1 == '/')
    {
        if (op2 == '+' || op2 == '-')
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}

function litter_number(ch){
	if((ch>='0' && ch<='9') || (ch>='a' && ch<='z')) return true;else return false;
}
// 中缀表达式转换成后缀表达式
function inFix2PostFix(expression)
{
    var j = 0, len;
    var c;
    var st=new Array();
	var postFix=new Array();
	var inFix=new Array();
	//将表达式分解为数组
	len=expression.length;
	var ch='';
	while(j<len){
		ch=expression.charAt(j);
		if(ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='(' || ch==')'){
			inFix.push(ch);	
			j++;
		}else if(litter_number(ch)){
			var val=ch;
			j++;
			while(j<len && litter_number(expression.charAt(j))){
				val+=expression.charAt(j);
				j++;	
			}
			inFix.push(val);
		}else j++;
	}
	//console.log(inFix);
	
    len = inFix.length;
    for (var i = 0; i < len; i++)
    {
        c = inFix[i];
        
        if (c == '(')//遇到左括号：将其入栈
            st.push(c);
        else if (c == ')')//遇到右括号：执行出栈操作，并将出栈的元素输出，直到弹出栈的是左括号，左括号不输出
        {
            while (st[st.length-1] != '(')
            {
                postFix.push(st[st.length-1]);
                st.pop();
            }
            st.pop();
        }
        else
        {
            if (!IsOperator(c))//遇到操作数：直接输出（添加到后缀表达式中）
                postFix.push(c);
            else
            {
				//遇到其他运算符：加减乘除：弹出所有优先级大于或者等于该运算符的栈顶元素，然后将该运算符入栈
                while (st.length>0
                       && Precedence(st[st.length-1], c) >= 0)
                {
                    postFix.push(st.pop());
                }
                st.push(c);
            }
        }
    }
	
    while (st.length>0)
    {
        postFix.push(st.pop());        
    }
    return postFix;
}

// 后缀表达式求值程序
function postFixEval(postFix)
{
    var st=new Array();
    var len = postFix.length;
    var c;

    for (var i = 0; i < len; i++)
    {
        c = postFix[i];
        if (IsOperator(c) == false)
        {

			if(isNaN(c)){
				var v=get_variable(c);
				st.push(v);
			}else   st.push(parseInt(c));//本程序只支持整数计算
        }
        else
        {
            var op1, op2;
            var val;

            op1 = st.pop();
            op2 = st.pop();
			//如果操作数是变量，则从变量是取出
			if(isNaN(op1)){
				op1=get_variable(op1);
			}
			if(isNaN(op2)){
				op2=get_variable(op2);	
			}
            switch (c)
            {
            case '+':
                val = op1 + op2;
                break;
            case '-':
                val = op2 - op1;
                break;
            case '*':
                val = op1 * op2;
                break;
            case '/':
                val = op2 / op1;
                break;
            }
            st.push(val);
        }
    }

    return st.pop();
}

function expression_value(expression){
	var a=inFix2PostFix(expression);
	//console.log(a);
	return postFixEval(a);
}